package com.os.sys.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.os.sys.mapper.RoleMenuMapper;
import com.os.sys.mapper.SysMenuMapper;
import com.os.sys.mapper.SysUserMapper;
import com.os.sys.mapper.UserRoleMapper;
import com.os.sys.pojo.SysMenu;
import com.os.sys.pojo.SysRole;
import com.os.sys.pojo.SysUser;
import com.os.sys.pojo.UserRole;
import com.os.sys.service.bean.MenuTreeNode;
import com.os.sys.service.bean.UserInfo;
import com.os.util.Tools;
import com.os.util.page.PageRequest;
import com.os.util.page.PageResult;
import com.os.util.page.PageUtils;
import entity.Param;
import lombok.extern.slf4j.Slf4j;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import util.IdWorker;

import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
@Transactional
@Slf4j
public class SysUserService {
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private UserRoleMapper userRoleMapper;
    @Autowired
    private RoleMenuMapper roleMenuMapper;
    @Autowired
    private SysMenuMapper sysMenuMapper;
    @Autowired
    private IdWorker idWorker;
    @Autowired
    private BCryptPasswordEncoder encoder;
    @Autowired
    HttpSession session;

    public List<SysUser> findAll(){
        log.info("this is findAll.");
        //return labelDao.findAll();
        Map map = new HashMap<>();
        map.put("condstr"," and true ");
        return sysUserMapper.selectByParam(map);
    }
    @Transactional
    public List<SysUser> selectByPage(Map map){
        List<SysUser> userList = sysUserMapper.selectByPage(map);
        return userList;
    }
    @Transactional
    public int selectCountByParam(Map map){
        return sysUserMapper.selectCountByParam(map);
    }

    /**
     * 采用分页且件进行分页
     * @param pageRequest
     * @param map
     * @return
     */
    public PageResult selectByPager(PageRequest pageRequest, Map map) {
        int pageNum = pageRequest.getPageNum();
        int pageSize = pageRequest.getPageSize();
        PageHelper.startPage(pageNum, pageSize);
        List<SysUser> sysUserList = sysUserMapper.selectByParam(map);
        Tools.indexOrder(sysUserList,"user_index");
        PageInfo pageInfo = new PageInfo<SysUser>(sysUserList);
        return PageUtils.getPageResult(pageRequest, pageInfo);
    }

    public SysUser selectById(String id){
        return sysUserMapper.selectById(id);
        // labelDao.findById(id).get();
    }

    public void insert(SysUser sysUser){
        //生成唯一ID
        sysUser.setUser_id(idWorker.nextId()+"");//设置ID
        //对前台传过来的密码进行加密
        if(sysUser.getUser_pwd()==null){
            sysUser.setUser_pwd("111111");
        }
        sysUser.setUser_pwd(encoder.encode(sysUser.getUser_pwd()));
        sysUserMapper.insert(sysUser);
    }
    /**
     * 修改用户信息-这里是一个异步处理的示例
     * @param sysUser
     */
    @Async
    public void update(SysUser sysUser){
        try {
            Thread.sleep(1000);
        }catch (Exception e){
            e.printStackTrace();
        }
        //labelDao.save(label);
        log.debug("begin update ..................................");
        sysUserMapper.update(sysUser);
    }

    public void deleteById(String id){
        sysUserMapper.deleteById(id);
    }

    //扩展方法 - 查询用户其它信息

    /**
     * 查询某个用户的角色
     * @param user_id
     * @return List<SysRole>
     */
    public List<SysRole> getUserRoles(String user_id){
        return userRoleMapper.selectRoleByUserId(user_id);
    }

    /**
     * 为多个用户配置角色,组织
     * 调用者：亲建或者更新用户时
     * @param user_ids  如:   1,2,3
     * @param role_ids
     * @param removeOldPerm 是否移除已有权限
     */
    public void setUserRoles(String user_ids, String role_ids, boolean removeOldPerm){
        //UserRoleDao userRoleDao = DaoFactory.getSysDaoFactory().getUserRoleDao();
        //UserOrgDao userOrgDao = DaoFactory.getSysDaoFactory().getUserOrgDao();
        log.info("setUserRoles.user_ids = "+user_ids+",role_ids = "+role_ids);
        if(StringUtils.isBlank(role_ids)){
            return;
        }
        if(removeOldPerm){
            if(user_ids.indexOf(",")<0){
                //Tools.getStr4Query(str, decorator)
                List<Param> paramList1 = new ArrayList();
                String role_ids_query = Tools.getStr4Query(role_ids, "");
                paramList1.add(new Param(""," user_id="+user_ids+" ","expr",""));
                paramList1.add(new Param(""," role_id not in ("+role_ids_query+")","expr",""));
                Map map = new HashMap();
                String condstr = Tools.genCondStr("a", paramList1);
                map.put("condstr", condstr);
                userRoleMapper.deleteByParam(map);
            }
        }
        log.info("user_ids = "+user_ids+":: role_ids = ");
        user_ids = user_ids.replace("[", "");
        user_ids = user_ids.replace("]", "");
        role_ids = role_ids.replace("[", "");
        role_ids = role_ids.replace("]", "");
        //log.debug("user_ids = "+user_ids+":: role_ids = "+role_ids+" :: org_ids ="+org_ids);
        String[] user_id_array = user_ids.split(",");
        String[] role_id_array = role_ids.split(",");
        //String[] org_id_array = org_ids.split(",");
        if(user_ids.indexOf(",")<0){
            user_id_array[0] = user_ids ;
        }
        if(role_ids.indexOf(",")<0){
            role_id_array[0] = role_ids ;
        }
//        if(org_ids.indexOf(",")<0){
//            org_id_array[0] = org_ids ;
//        }
        for(int i=0; i<user_id_array.length; i++){
            String user_id = user_id_array[i];
            if(user_id.length()==0){
                continue;
            }
            //角色信息
            for(int j=0; j<role_id_array.length; j++){
                String role_id = role_id_array[j];
                //log.debug("role_id = "+role_id);
                if(role_id.length()==0){
                    continue;
                }
                log.info("role_id = "+role_id);
                UserRole userRole = userRoleMapper.selectByRoleIdUserId(Integer.valueOf(role_id), user_id);
                //log.debug(userRole);
                if(userRole==null){
                    log.info("为用户增加角色:"+role_id);
                    userRole = new UserRole();
                    userRole.setUser_id(user_id);
                    userRole.setRole_id(Integer.valueOf(role_id));
                    userRoleMapper.insert(userRole);
                }else{
                    log.info("当前用户已经有角色:"+role_id);
                }
            }
        }

    }

    /**
     * 执行登陆验证
     * @param user_name
     * @param password
     * @return
     */
    public SysUser login(String user_name, String password) {
        //Map map = new HashMap();
        //map.put("user_phone", phone);
        //map.put("condstr", " and user_phone = '"+phone+"' ");
        SysUser sysUser = sysUserMapper.selectByUserName(user_name);
        if(sysUser!=null){
            return sysUser;
        }
        if(sysUser!=null && encoder.matches(password, sysUser.getUser_pwd())){
            return sysUser;
        }
        return null;
    }

    public UserInfo genUserInfo(SysUser sysUser){
       UserInfo userinfo = new UserInfo();
       userinfo.setSysUser(sysUser);
       session.setAttribute("userInfo", userinfo);
       return userinfo;
    }

    /**
     * 查询用户的菜单
     * @param user_id
     * @return
     */
    public List<MenuTreeNode> queryUserMenu(String user_id){
        //一级菜单
        List<MenuTreeNode> menuTreeNodeList = new ArrayList();
        //二级菜单
        List<MenuTreeNode> menuTreeNodeListLv2 = new ArrayList();

        List<SysRole> sysRoleList = userRoleMapper.selectRoleByUserId(user_id);
        List<Integer> idList = new ArrayList<>();
        for (int i = 0; i <sysRoleList.size() ; i++) {
            idList.add(sysRoleList.get(i).getRole_id());
        }
        List<SysMenu> sysMenuList = roleMenuMapper.selectSysMenuByRoleIds(idList);
        //构造菜单树
        String menu_ids = Tools.getIdsFromList(sysMenuList, "menu_id");
        menu_ids = Tools.getDistinctStr(menu_ids);//去重  用户如果有多个角色，可以设置的菜单会重复
        menu_ids = ","+menu_ids+",";
        //System.out.println(menu_ids);
        //查找一级结点
        for(int i=0 ; i<sysMenuList.size(); i++){
            SysMenu sysMenu = sysMenuList.get(i);
            String code = sysMenu.getMenu_code();
            int menu_id = sysMenu.getMenu_id();
            String menu_id_temp = ","+menu_id+",";
            //取用户具备的，一级菜单, 如：100000000000
            if(code.indexOf("0000000000")>0 && menu_ids.indexOf(menu_id_temp)>=0){
                MenuTreeNode node = new MenuTreeNode();
                node.setMenu_id(sysMenu.getMenu_id());
                node.setMenu_addr(sysMenu.getMenu_addr());
                node.setMenu_name(sysMenu.getMenu_name());
                node.setMenu_code(sysMenu.getMenu_code());
                node.setM_p(sysMenu.getMenu_parent());
                node.setImg(sysMenu.getMenu_img());
                menuTreeNodeList.add(node);
            }
        }
        for(int i=0; i<menuTreeNodeList.size(); i++){
            MenuTreeNode menuTreeNode =menuTreeNodeList.get(i);
            List<MenuTreeNode> childNodes = new ArrayList();
            int menu_id = menuTreeNode.getMenu_id();
            List<SysMenu> sysMenuListLv2 = sysMenuMapper.selectChildmenu(menu_id);
            for(int j=0 ; j<sysMenuListLv2.size(); j++){
                SysMenu sysMenuLv2 = sysMenuListLv2.get(j);
                String menu_id_temp = ","+sysMenuLv2.getMenu_id()+",";
                if(sysMenuLv2.getMenu_code().indexOf("00000000")>0 && menu_ids.indexOf(menu_id_temp)>=0){
                    MenuTreeNode node = new MenuTreeNode();
                    node.setMenu_id(sysMenuLv2.getMenu_id());
                    node.setMenu_addr(sysMenuLv2.getMenu_addr());
                    node.setMenu_name(sysMenuLv2.getMenu_name());
                    node.setMenu_code(sysMenuLv2.getMenu_code());
                    node.setM_p(sysMenuLv2.getMenu_parent());
                    node.setImg(sysMenuLv2.getMenu_img());
                    childNodes.add(node);
                    //保存二级菜单
                    menuTreeNodeListLv2.add(node);
                }
            }
            menuTreeNode.setChildren(childNodes);
        }
        //为每个二级结点设置三级结点
        List <MenuTreeNode> nodeListLv2 = new ArrayList();
        List <MenuTreeNode> nodeListLv3 = new ArrayList();
        for(int i=0; i<menuTreeNodeList.size(); i++){
            nodeListLv2 = menuTreeNodeList.get(i).getChildren();
            for(int j=0; j<nodeListLv2.size(); j++){
                MenuTreeNode nodeLv2 = nodeListLv2.get(j);
                int menu_id = nodeLv2.getMenu_id();
                //一级菜单ID
                int m_p = nodeLv2.getM_p();
                //查找当前二级结点的三级菜单
                List<SysMenu> sysMenuListLv3 = sysMenuMapper.selectChildmenu(menu_id);
//				System.out.println("二级menu_id：： "+menu_id);
//				for(int s=0; s<sysMenuListLv3.size(); s++){
//					System.out.println("三级：： "+sysMenuListLv3.get(s).getPrintStr());
//				}
                nodeListLv3 = new ArrayList();
                for(int k=0 ; k<sysMenuListLv3.size(); k++){
                    SysMenu sysMenuLv3 = sysMenuListLv3.get(k);
                    String menu_id_temp = ","+sysMenuLv3.getMenu_id()+",";
                    if(sysMenuLv3.getMenu_code().indexOf("000000")>0 && menu_ids.indexOf(menu_id_temp)>=0){
                        MenuTreeNode node = new MenuTreeNode();
//                        if(!isFinMenu(sysMenuLv3.getMenu_id())){
//                            //提取三级菜单下的四级,五级
//                            node = getTree(sysMenuLv3.getMenu_id(),1);
//                        }
                        node.setMenu_id(sysMenuLv3.getMenu_id());
                        node.setMenu_addr(sysMenuLv3.getMenu_addr());
                        node.setMenu_name(sysMenuLv3.getMenu_name());
                        node.setMenu_code(sysMenuLv3.getMenu_code());
                        node.setM_p(m_p);
                        node.setImg(sysMenuLv3.getMenu_img());
                        //node.setAppUri(appUri);
                        //node.setM_f(sysMenuLv3.getMenu_frm());
                        nodeListLv3.add(node);
                        //System.out.println("三级 node：： "+node.getMenu_code());
                    }
                }
                nodeLv2.setChildren(nodeListLv3);
            }
        }
        //return menuTreeNodeList;
        return menuTreeNodeListLv2;
    }
}
